home *** CD-ROM | disk | FTP | other *** search
- *********************************************************************
- This article is being presented through the *StarBoard* Journal of
- the FlagShip/StarShip, SIGS (Special Interest Groups) on the
- Delphi and GEnie telecommunications networks. Permission is
- hereby granted to non-profit organizations only to reprint this
- article or pass it along electronically as long as proper credit
- is given to both the author and the *StarBoard* Journal.
- *********************************************************************
-
- THE ABC's OF BCD (part 2)
-
- Manipulating Decimal Numbers In Machine Language
-
- by W.J. Brier
-
- (TROUBLESOME on DELPHI)
-
- ===========================================================================
- INTRODUCTION
-
- If you have thoroughly read THE ABC'S OF BCD part 1 and have tried out the
- program examples that were presented, you should have an elementary
- understanding of binary coded decimal (BCD) numbers. If some of the
- concepts presented in part 1 are not clear, I suggest that you read over
- the material again and try out the program examples before continuing on
- with part 2 of this series.
-
- In part 1 you were presented with the basic concept of binary coded decimal
- numbers and were shown how to store such numbers. Routines were presented
- that illustrated the techniques of encoding a two digit ASCII number into a
- single BCD digit and decoding a single BCD digit back to ASCII numerals.
- With this information safely tucked away in your mind, let's move onward to
- new ground.
-
- In THE ABC'S OF BCD part 2, methods of encoding and decoding multi-digit
- numbers will be discussed. Also, the technique of stripping leading and
- trailing zeros, and the right justification of dollars and cents numbers,
- will be explored. Program examples will continue to use the same symbology
- used in part 1 of the series.
-
- I. ENCODING ASCII DECIMAL STRINGS TO BCD NUMBERS
-
- Before any type of mathematical operation can be performed on an ASCII
- number, it must be encoded into a form suitable for use by the computer.
- The BASIC interpreter, you may recall, changes ASCII decimal numbers into
- five byte binary format. This process occasionally introduces errors that
- are the natural result of converting from one number base (base 10) to
- another (base 2). However, the system being discussed here is a decimal
- system and will not result in conversion errors.
-
- The first step in encoding an ASCII decimal string into a BCD number is to
- format the string in such a manner that it always is a standard length,
- with the decimal point in fixed position. This requires that the string be
- scanned to find its length and decimal point position. Once these two
- items have been determined the string must be padded with zeros if it is
- shorter than the standard length required by the encoding program. This
- process is referred to as NORMALIZING.
-
- Only after normalizing has been performed can BCD encoding be accomplished.
- Although it will not be discussed at this time, means should be developed
- to prevent an overflow condition due to an excessively large ASCII number
- being input into the program. An overflow will result in a grossly
- inaccurate BCD number due to truncating of the highest digits. If the
- number has too many places to the right of the decimal point, the excess
- will also be truncated, resulting in some additional inaccuracy. To some
- extent this can be avoided by testing the length of the ASCII input string
- and making appropriate corrections.
-
- Before presenting an example of how to encode an ASCII number into BCD, I'd
- like to discuss what is meant by normalizing the ASCII string. Let's
- suppose that the user types in the ASCII floating point number:
-
- 256.781
-
- Let's further suppose that the ASCII to BCD encoding algorithm allows four
- places to the right of the decimal point and six places to the left.
- Formatting the above input to the normalized format imposed by these place
- limits results in:
-
- 000256.7810
-
- As can be seen, the string has been padded with ASCII zeros to fill in the
- unused places on either side of the decimal point. The original input has
- been change to the normalized format. Let's look at a few more examples,
- using the place limits imposed above, so as to better understand this
- process:
-
- INPUT NORMALIZED
- ===================================
- 100 000100.0000
- .0004 000000.0004
- 21.786 000021.7860
- 423098.45238 423098.4523
- 2345.28 002345.2800
- 0.002307 000000.0023
- ===================================
-
- It is apparent from the fourth and sixth examples that excess digits to the
- right of the decimal point are simply lost. The resulting BCD number will,
- of course, be slightly inaccurate due to this truncation. It is also
- apparent that the decimal point is no longer necessary to represent the
- number. Because the string has been changed to the normalized format, the
- decimal point is now understood to be between the sixth and seventh digits
- of the string and thus may be ignored.
-
- As the normalized format in this case is limited to ten digits total, the
- user input should likewise be restricted to a maximum of ten digits and one
- decimal point. An input format checking algorithm should be used to filter
- out strings that fail to conform to these limits or that have non-numeric
- characters.
-
- Ignoring the decimal point reduces the input to a normalized format of ten
- ASCII digits, with zeros padding the unused positions. The above table in
- this format will look like this:
-
- INPUT NORMALIZED
- ===================================
- 100 0001000000
- .0004 0000000004
- 21.786 0000217860
- 423098.45238 4230984523
- 2345.28 0023452800
- 0.002307 0000000023
- ===================================
-
- With the ASCII decimal string normalized, the encoding process is greatly
- simplified. The actual procedure for normalizing will now be discussed.
-
- As with encoding a pair of ASCII digits into a single BCD digit, a logical
- procedure should be followed. It is assumed that the ASCII number to be
- encoded is in a storage area that will be referred to as BUF (for input
- buffer) and that the string is terminated by a null ($00):
-
- 1. Clear the ASCII accumulator (ACUMA) by filling it with ASCII
- zeros;
-
- 2. Scan the ASCII input string to locate the decimal point (if
- any);
-
- 3. Starting at the digit immediately to the left of the decimal
- point location, transfer digits from BUF to ACUMA in descending
- order;
-
- 4. Starting at the digit immediately to the right of the decimal
- point location, transfer digits from BUF to ACUMA in ascending
- order.
-
- That essentially is all there is to it. A suitable algorithm to accomplish
- this will now be presented.
-
- This algorithm will be structured as a subroutine and will be referred to
- with the label FRMAT (the routine does not check for a negative number):
-
- FRMAT LDA #$48 ;ASCII ZERO
- LDX #$09 ;ACUMA OFFSET
- ;
- FRMAT1 STA ACUMA,X ;FILL ACCUMULATOR WITH ZEROS
- DEX
- BPL FRMAT1 ;LOOP
- ;
- LDX #$00 ;USE .X AS BUF OFFSET
- ;
- FRMAT2 LDA BUF,X ;FETCH INPUT BYTE
- BEQ FRMAT3 ;END OF STRING
- ;
- CMP #$2E ;ASCII DECIMAL POINT
- BEQ FRMAT3 ;DECIMAL POINT FOUND
- ;
- INX ;NEXT CHARACTER
- BNE FRMAT2 ;LOOP
- ;
- FRMAT3 TXA ;SAVE LOCATION IN BUF...
- PHA ;ON STACK
- DEX ;SKIP DECIMAL POINT OR NULL
- ;
- LDY #$05 ;ACUMA OFFSET
- ;
- FRMAT4 LDA BUF,X ;FETCH ASCII DIGIT
- STA ACUMA,Y ;STORE IN ACCUMULATOR
- DEY ;CHANGE ACUMA OFFSET
- DEX ;CHANGE BUF OFFSET
- BPL FRMAT4 ;LOOP
- ;
- PLA ;FETCH DECIMAL/NULL LOCATION
- TAX ;BECOMES BUF OFFSET
- LDY #$06 ;ACUMA OFFSET
- ;
- FRMAT5 LDA BUF,X ;FETCH ASCII DIGIT
- BEQ FRMATO ;END OF INPUT STRING
- ;
- CMP #$2E ;DECIMAL POINT?
- BEQ FRMAT6 ;YES, SKIP
- ;
- STA ACUMA,Y ;STORE DIGIT
- INY ;NEW ACUMA OFFSET
- ;
- FRMAT6 INX ;NEW BUF OFFSET
- BNE FRMAT5 ;LOOP
- ;
- FRMATO RTS ;EXIT
-
- Upon entering this subroutine the first operation performed is fill the
- ASCII accumulator (ACUMA) with ASCII zeros. Then the input string in BUF
- is scanned (starting at the loop at FRMAT2) until the decimal point has
- been located, using the .X register as an offset. If the end of the input
- string is reached (which would be detected by loading the terminating
- null), the scan is aborted. Otherwise, looping continues until the decimal
- point is found at which time the scan is terminated. The current BUF
- offset in .X is saved on the stack.
-
- Next, the ASCII digits starting to the left of the decimal point in BUF are
- transferred to ACUMA via the loop set up at FRMAT4. Note that the ACUMA
- offset in the .Y register starts by pointing at the digit immediately to
- the left of the assumed decimal point location in ACUMA. Upon completion
- of this transfer, the decimal point location in BUF is pulled from the
- stack and now digits to the right of the decimal point are moved to ACUMA,
- via the loop at FRMAT5. The loop terminates when the null at the end of
- BUF is reached, indicating that there are no more characters to transfer.
-
- Because ACUMA was filled with zeros before any transferring was performed,
- any unused locations in ACUMA will still contain zeros and thus will result
- in the ASCII string being properly padded. Here is what ACUMA would look
- like at each of the three major points in the routine. It is assumed that
- the ASCII input string 1371.08 is being formatted:
-
- LABEL ACUMA
- ===================
- FRMAT2 0000000000
- FRMAT5 0013710000
- FRMATO 0013710800
- ===================
-
- It is apparent from the foregoing that normalizing permits the entry of
- floating point decimal numbers, as the actual location of the decimal point
- is determined during the formatting operation. The result however is
- always a string in normalized format. With the ASCII number properly
- formatted, ASCII to BCD conversion may now be performed.
-
- As you may recall, in THE ABC'S OF BCD part 1 a subroutine (ASBCD) was
- presented that would convert two ASCII digits into a single BCD digit. By
- using ASBCD within a loop it is possible to encode the entire number
- contained in ACUMA, the result being deposited in BCD accumulator ACUM1.
- This is accomplished by successively fetching characters from the ASCII
- string, calling the conversion subroutine and storing the resulting BCD
- digit in ACUM1. Two offsets are required for this purpose, one to keep
- track of the current location within ACUMA and the other to maintain
- position in ACUM1.
-
- In the formatting example presented above, a normalized ASCII number is ten
- digits, six to the left of the decimal point and four to the right. The
- arrangement of the BCD accumulators obviously must reflect this format, as
- there is a two-for-one relationship between the ASCII string and its BCD
- equivalent. Thus ACUM1 and ACUM2, in this case, would be five bytes in
- length, with the decimal point assumed to be between the third and fourth
- byte.
-
- Here is an algorithm to convert the normalized ASCII number in ACUMA to a
- BCD number in ACUM1 (using the above value). This subroutine will be
- labeled ENCD:
-
- ENCD LDY #0 ;ACUMA OFFSET
- STY SFLG1 ;ACUM1 OFFSET
- ;
- ENCD1 LDA ACUMA,Y ;FETCH TENS DIGIT
- TAX ;GIVE TO .X REGISTER
- INY ;NEXT DIGIT
- LDA ACUMA,Y ;FETCH UNITS DIGIT
- JSR ASBCD ;CALL CONVERSION ROUTINE
- ;
- LDX SFLG1 ;FETCH ACUM1 OFFSET
- STA ACUM1,X ;SAVE BCD DIGIT
- ;
- INC SFLG1 ;BUMP ACUM1 OFFSET
- ;
- INY ;BUMP ACUMA OFFSET
- CPY #$0A ;END OF ACUMA?
- BNE ENCD1 ;NO, SO LOOP
- ;
- RTS ;EXIT
-
- Upon exit from this routine the ASCII number in ACUMA will be in BCD format
- in ACUM1 (ACUMA is left undisturbed). For the purposes of conversion each
- pair of ASCII digits fetched from ACUMA is treated as a units and tens pair
- by ASBCD. The .Y register keeps track of the position within ACUMA (.Y is
- not disturbed by ASBCD). The ACUM1 offset has to be kept in RAM as the .X
- register is used by the ASBCD subroutine. Assuming that the ASCII number
- 1371.08 is being encoded, here are the stages that ACUM1 will go through
- during each iteration of the routine (ACUM1 values are in hex):
-
- CYCLE ACUM1
- =======================
- Start ** ** ** ** **
- 1 00 ** ** ** **
- 2 00 13 ** ** **
- 3 00 13 71 ** **
- 4 00 13 71 08 **
- 5 00 13 71 08 00
- =======================
-
- The asterisks indicate random values that may be in ACUM1 from a previous
- operation.
-
- To summarize this chapter, converting an ASCII decimal number requires that
- it be normalized and then encoded two digits at a time into a series of
- single BCD digits, these digits being stored in the BCD accumulator. With
- a basic understanding of this process, let's go on to the next step,
- converting a BCD number back to an ASCII decimal string.
-
- II. DECODING BCD NUMBERS TO ASCII DECIMAL STRINGS
-
- Before a BCD number can be displayed to the user it must be decoded and the
- resulting string of ASCII digits must be formatted in a manner suitable for
- use by the display routine. Formatted ASCII strings may also be JUSTIFIED
- so that all decimal points align in a columnar display. Justification is
- useful for displaying columns of figures and lends a professional
- appearance to the display. In some cases however, justification may not be
- desirable.
-
- BCD to ASCII conversion requires no special preparation of the BCD number,
- unless it is negative (which may be the result of some mathematical
- operation). If the number is negative then the sign flag for the
- accumulator must be set to indicate this fact and the sign bit in the first
- BCD digit cleared.
-
- Once the sign of the BCD number has been established, a loop is set up to
- successively decode each BCD digit to its corresponding ASCII values, these
- values being deposited in the ASCII accumulator (ACUMA). As with the
- encoding routine presented above, two offsets are required to maintain
- position in both the BCD and ASCII accumulators. The examples to be
- presented will assume that the number to decode is in the BCD accumulator
- (ACUM1). The ASCII equivalent will be stored in ACUMA. Part of the
- decoding routine of course, is to insert a decimal point at the correct
- location in the ASCII string.
-
- The decoding routine to be presented always places the decimal point at the
- same location in the ASCII accumulator. Let's first look at how some BCD
- numbers would appear after decoding, but before any additional formatting
- (accumulator sizes are as they were in the previous examples on encoding to
- BCD):
-
- BCD Number ASCII String
- =====================================
- 00 00 00 00 00 000000.0000*
- 00 13 71 08 00 001371.0800*
- 71 00 61 00 03 710061.0003*
- 00 00 00 00 77 000000.0077*
- 80 04 29 03 11 -00429.0311*
- 82 92 03 04 00 -29203.0400*
- =====================================
-
- The asterisks represent the terminating null ($00) at the end of each ASCII
- string.
-
- In examining these numbers a distinct set of patterns emerge. The decimal
- point is always the seventh character in the string and when the BCD number
- is negative the minus sign (-) replaces the digit in the first character.
- The string is padded with zeros. Formatting would be used to remove the
- leading and/or trailing zeros if they are not desired in the display.
-
- Here is an algorithm to decode the BCD number contained in BCD accumulator
- ACUM1:
-
- DECD LDX #$00
- LDY #$00 ;ACUMA OFFSET
- STX SFLG1 ;CLEAR SIGN FLAG
- STX ACUMA+11 ;ASCII STRING TERMINATOR
- ;
- LDA ACUM1 ;CHECK SIGN OF BCD NUMBER
- BPL DECD1 ;POSITIVE NUMBER
- ;
- DEC SFLG1 ;SET SIGN FLAG TO NEGATIVE
- AND #$7F ;MASK SIGN BIT
- STA ACUM1 ;SAVE IN ACCUMULATOR
- ;
- DECD1 STX SFLG2 ;ACUM1 OFFSET
- ;
- LDA ACUM1,X ;FETCH BCD DIGIT
- JSR BCDAS ;CALL DIGIT DECODING ROUTINE
- ;
- STA ACUMA,Y ;SAVE TENS DIGIT
- INY ;BUMP OFFSET
- TXA
- STA ACUMA,Y ;SAVE UNITS
- INY ;BUMP OFFSET
- CPY #$06 ;TIME FOR DECIMAL POINT?
- BNE DECD2 ;NO
- ;
- LDA #$2E ;ASCII DECIMAL POINT
- STA ACUMA,Y ;STORE
- INY ;BUMP OFFSET
- ;
- DECD2 LDX SFLG2 ;ACUM1 OFFSET
- INX
- CPX #$05 ;FINISHED?
- BNE DECD1 ;NO, SO LOOP
- ;
- BIT SFLG1 ;CHECK SIGN
- BPL DECDO ;POSITIVE NUMBER
- ;
- LDA #$2D ;ASCII MINUS SIGN
- STA ACUMA ;STORE
- ;
- DECDO RTS ;EXIT
-
- Upon exit from this routine, ACUMA will contain the ASCII string
- corresponding to the BCD number in ACUM1.
-
- The first character of ACUMA will contain a minus sign if the BCD number
- was negative. The routine loops five times to accomplish its task. Here
- are the successive stages that ACUMA would go through for each iteration
- (ACUM1 is assumed to contain $00 $13 $78 $08 $00):
-
- ITERATION ACUMA
- ======================
- Start ***********
- 1 00*********
- 2 0013*******
- 3 001378.****
- 4 001378.08**
- 5 001378.0800
- ======================
-
- In this example the asterisks represent random values that may be in the
- ASCII accumulator from a previous operation. Note that when the value in
- the .Y register reaches six the routine inserts a decimal point into ACUMA
- and increments .Y so that the next digit will follow the decimal point.
- The BCDAS routine was presented in part 1 of this series and illustrated
- the technique of decoding a BCD digit. You may wish to refer to that
- routine if you aren't sure as to where the values came from.
-
- The first step of the decoding process is to determine the sign of the BCD
- number. As you may recall, the seventh bit of the first BCD digit is set
- if the number is negative. Thus, loading the .A register with the first
- digit either sets Ar clears the N flag in the CPU status register. The
- routine uses that fact to determine sign and set the sign flag SFLG1 if the
- BCD number is negative. Before actually decoding a negative number, the
- seventh bit must be cleared via use of the AND operation to avoid an
- erroneous result from BCDAS. Here is an example of how this would operate:
-
- .A Register 1000 0110 = $86
- AND #$7F 0111 1111 = $7F
- ================================
- .A Register 0000 0110 = $06
-
- With the sign taken care of, the BCD digits are fetched one at a time,
- decoded and the resulting ASCII digits are stored in ACUMA. The offsets
- are then incremented accordingly, the ACUM1 offset also acting as a loop or
- iteration counter. Since there are five BCD digits to decode five
- iterations are performed. After the last iteration, the sign flag SFLG1 is
- examined with the BIT instruction. If the decoded BCD number is negative
- the routine simply places a minus sign into the first byte of ACUMA.
- Otherwise, the byte is not disturbed.
-
- At this point ACUMA contains an ASCII string which may be padded with
- leading and trailing zeros. Prior to actually displaying the number, it
- may be desirable to perform some additional formatting on the string to
- modify its appearance.
-
- III. FORMATTING ASCII DECIMAL STRINGS
-
- When displaying numbers on the screen or printer it is often desirable to
- have them conform to a certain appearance. For example, you may want
- trailing zeros and decimal points aligned (justified) or you may want all
- numbers to start at the same point on the screen or page. To accomplish
- these goals some type of formatting is usually required.
-
- As decoded, the string in ACUMA has the decimal point in the seventh
- character position and may have leading and/or trailing zeros, depending on
- the BCD number that was decoded. Because the decimal point is always in
- the same location (fixed) the string may be considered justified as it
- sits. In the majority of the cases, you will want to strip the leading
- zeros from the string for display. That can be accomplished by replacing
- leading zeros with blanks (ASCII 32) from within a loop. When the first
- non-zero character is found, the loop is terminated. The procedure is
- slightly complicated by the possibility of a minus sign being found in the
- first character position.
-
- Here is an algorithm to strip the leading zeros from an ASCII decimal
- string in ACUMA:
-
- LDSTP LDY #0 ;OFFSET
- ;
- LDSTP1 LDA ACUMA,Y ;FETCH CHARACTER
- CMP #$2D ;ASCII MINUS SIGN
- BEQ LDSTP2 ;SKIP
- ;
- CMP #$2E ;ASCII DECIMAL POINT
- BEQ LDSTPO ;TERMINATE LOOP
- ;
- CMP #$30 ;ASCII ZERO
- BNE LDSTPO ;TERMINATE LOOP
- ;
- LDA #$20 ;ASCII BLANK
- STA ACUMA,Y ;REPLACE LEADING ZERO
- ;
- LDSTP2 INY ;BUMP OFFSET
- BNE LDSTP1 ;LOOP
- ;
- LDSTPO RTS ;EXIT
-
- The routine requires up to 6 iterations to complete this operation, the
- actual number of iterations depending on the number of leading zeros found.
-
- Understanding how it works is best accomplished by looking at how a string
- is changed in each iteration:
-
- iteration ACUMA
- =====================
- Start -00045.8600
- 1 -00045.8600 (minus sign is ignored)
- 2 - 0045.8600
- 3 - 045.8600
- 4 - 45.8600
- =====================
-
- If all characters before the decimal point are zeros:
-
- 000000.0432
-
- the routine will strip the zeros until it reaches the decimal point,
- resulting in:
-
- .0432
-
- If you wish to retain one leading zero, simply change the code at LDSTP2 to
- this:
-
- LDSTP2 INY ;BUMP OFFSET
- CPY #$05
- BNE LDSTP1 ;LOOP
- ;
- (program continues...)
-
- This would format:
-
- 000000.0432
-
- to:
-
- 0.0432
- a format style often desired in scientific and engineering calculations.
-
- The preceding routine stripped the leading zeros from the ASCII string.
- You may wish to strip trailing zeros as well. As with the previous
- technique, the routine stops upon reaching the first non-zero character in
- the string. In this case however, the routine starts from the tenth
- character position in ACUMA and works in reverse.
-
- Here is a routine to replace trailing zeros with blanks:
-
- TRSTP LDX #$20 ;ASCII BLANK
- LDY #$0A ;OFFSET
- ;
- TRSTP1 LDA ACUMA,Y ;FETCH CHARACTER
- CMP #$30 ;ASCII ZERO
- BNE TRSTP2 ;TERMINATE LOOP
- ;
- TXA
- STA ACUMA,Y ;SUBSTITUTE BLANK
- ;
- DEY ;LOWER OFFSET
- BNE TRSTP1 ;LOOP
- ;
- TRSTP2 CMP #$2E ;DECIMAL POINT?
- BNE TRSTPO ;NO, IGNORE CHARACTER
- ;
- TXA
- STA ACUMA,Y ;REMOVE DECIMAL POINT
- ;
- TRSTPO RTS ;EXIT
-
- The effect of this and the previous routine for stripping leading zeros is
- again best understood by looking at some strings before and after
- formatting:
-
- UNFORMATTED LEADING STRIP TRAILING STRIP
- ================================================
- 006492.8900 6492.8900 6492.89
- 172492.0000 172492.0000 172492
- 000000.0000 .0000
- 000000.0123 .0123 .0123
- -00076.1030 - 76.1030 - 76.103
- ================================================
-
- About this time you are probably wondering what happened to the string in
- the third example. No, it isn't a typographical error. Stripping all of
- the leading zeros and stripping all of the trailing zeros results in a
- completely blank string (all ASCII 32). Naturally, that isn't desirable.
- For that reason it is best to use the modified version of LDSTP (see
- above), which always leaves a zero immediately before the decimal point.
- Thus:
-
- 000000.0000
-
- formats to:
-
- 0
-
- a much more meaningful result. With the concept of stripping leading and
- trailing zeros in mind, let's go on to alternate types of formatting.
-
- The effect of stripping trailing zeros in the above routine is to replace
- them with blanks. The result of this is that when combined with the
- stripping of leading zeros the string remains the same length as before
- stripping. Obviously this is very handy when printing columns of numbers
- as it makes it easy to format the display itself (the end of one string and
- the beginning of the next are always a fixed distance from each other).
- Certain displays however, may require that the numbers not be justified.
- For example, you may wish to print:
-
- ACCOUNT BALANCE $1867.29 ON 11-16-85
-
- To achieve such a display, leading zeros must be stripped and the string
- must then be dejustified. Also, two characters to the right of the decimal
- point should be retained so that even dollar amounts don't end up with a
- strange appearance. The first step after stripping the leading zeros is to
- insert a new terminator ($00) into ACUMA so as to leave two characters to
- the right of the decimal point. Since the decimal point is known to be in
- the seventh character position it can be deduced that the new terminator
- should be stored at the tenth character position:
-
- LDA #$00 ;TERMINATOR
- STA ACUMA+9 ;TRUNCATE STRING
-
- Next, the string must be shifted left in ACUMA to eliminate the blanks that
- were used to replace the leading zeros during the stripping process. This
- is accomplished by using two offsets, one to locate the non-blank
- characters and the other to relocate the characters closer to the beginning
- of the accumulator. The resulting loop terminates when the terminator null
- is located. Here is an algorithm to dejustify a string in ACUMA:
-
- DJUST LDX #$00 ;FETCH OFFSET
- LDY #$00 ;STORAGE OFFSET
- ;
- DJUST1 LDA ACUMA,X ;FETCH CHARACTER
- BEQ DJUSTO ;END OF STRING
- ;
- CMP #$20 ;ASCII BLANK
- BEQ DJUST2 ;DISCARD
- ;
- STA ACUMA,Y ;STORE NON-BLANK CHARACTER
- INY ;BUMP STORAGE OFFSET
- ;
- DJUST2 INX ;BUMP FETCH OFFSET
- BNE DJUST1 ;LOOP
- ;
- DJUSTO STA ACUMA,Y ;TERMINATOR
- ;
- RTS ;EXIT
-
- The number of iterations required by this routine will depend upon the
- terminator position in ACUMA. Here is the effect upon a stripped string in
- ACUMA during each pass through the routine:
-
- ITERATION ACUMA
- ===================
- Start - 62.87*
- 1 - 62.87* (skip minus sign)
- 2 - 62.87* (skip blank)
- 3 - 62.87* (skip blank)
- 4 - 62.87* (skip blank)
- 5 -6 62.87*
- 6 -62 62.87*
- 7 -62.62.87*
- 8 -62.82.87*
- 9 -62.87.87*
- 10 -62.87*87*
- ===================
-
- The terminator is represented by the asterisk. Note that at the end of the
- tenth iteration the terminator has been moved from the tenth position to
- the seventh position in ACUMA. The result of this is that characters after
- the seventh position will be ignored in subsequent operations.
-
- IV. RECAP
-
- The preceding chapters have described techniques for converting ASCII to
- BCD and vice versa, building upon the knowledge gained in THE ABC'S OF BCD
- part 1. Prior to continuing to part 3, code in the example routines and
- run them to see what happens. Try overflowing the ASCII accumulator to see
- what result it has upon the equivalent BCD number. If you are using a
- C-128 the memory area in RAM 0 from $0C00 to $0DFF is a good place to
- practice as it is undisturbed (unless using the RS-232 routines).
-
- In THE ABC'S OF BCD part 3, the subject of transferring BCD numbers from
- one location to another and the techniques of signed addition and
- subtraction will be discussed. Here you will learn how to perform math
- operations upon your BCD numbers. When combined with the conversion and
- formatting techniques described above, you will have the makings of a
- machine language math package based entirely on the decimal numbering
- system.